#pragma	once

#include "ZCommon.h"
#include "ZStreamVerifier.h"
#include "ZPoolObject.h"
#include "ZUtility.h"
#include <assert.h>

namespace	Z	{

//------------------------------------------------------------------------------------------------------------------------
class	_ZMainApi	StreamBuf
	:	public PoolObject
{
public:
	explicit	StreamBuf(size_t kSize)	:	mInitialAllocSize(kSize),	mAllocSize(kSize),	mBuffer(nullptr)	{
		assert(0 < kSize);
		allocate(kSize);
	}
	virtual	~StreamBuf()	{
		deallocate();
	}
	operator	byte_t*()		const	{
		return getBuffer();
	}
	operator	char*()	const	{
		return reinterpret_cast<char*>(getBuffer());
	}
	byte_t*	getBuffer()	const	{
		return mBuffer;
	}
	size_t	getAllocSize()	const	{
		return mAllocSize;
	}
protected:
	void	reallocate(size_t kSize)	{
		assert(mBuffer != nullptr);
		assert(mAllocSize < kSize);

		mBuffer	= (byte_t*)::realloc(mBuffer, mAllocSize = kSize);
		assert(mBuffer != nullptr);
	}
	void	allocate(size_t kSize)	{
		assert(mBuffer == nullptr);

		mBuffer	= (byte_t*)::malloc(mAllocSize = kSize);
	}
	void	deallocate()	{
		assert(mBuffer != nullptr);

		::free(mBuffer);
		mBuffer	= nullptr;
	}
	size_t	getInitialAllocSize()	const	{
		return mInitialAllocSize;
	}

private:
	const	size_t	mInitialAllocSize;
	size_t	mAllocSize;
	byte_t*	mBuffer;

	friend	ReadStreamVerifier;
	friend	WriteStreamVerifier;
};

}